package iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.service.serviceImpl;

import static com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer.deserializeFromString;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.IBinder;
import android.util.Base64;
import android.util.Log;

import androidx.annotation.Nullable;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.dal.ProductInfoDAL;
import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.dal.TraceInfoDAL;
import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.entity.Product;
import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.entity.Trace;
import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.service.IProductService;

public class ProductService extends Service implements IProductService {
    private final IBinder binder = new ProductService.LocalBinder();
    private ProductInfoDAL productInfoDAL;
    private TraceInfoDAL traceInfoDAL;
    private SharedPreferences sharedPreferences;

    public class LocalBinder extends Binder {
        public ProductService getService() {
            return ProductService.this;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        productInfoDAL = new ProductInfoDAL(this);
        traceInfoDAL = new TraceInfoDAL(this);
    }

    public void setProductInfoDAL(ProductInfoDAL productInfoDAL, TraceInfoDAL traceInfoDAL) {
        this.productInfoDAL = productInfoDAL;
        this.traceInfoDAL = traceInfoDAL;
    }

    @Override
    public Boolean addProduct(Product newProduct) {
        return productInfoDAL.addOneProduct(newProduct) > 0;
    }

    @Override
    public Boolean deleteProduct(String productId) {
        return productInfoDAL.deleteProduct(productId) > 0;
    }

    @Override
    public Boolean updateProductInfo(Product newProduct) {
        return productInfoDAL.updateProductBaseInfo(newProduct) > 0;
    }

    @Override
    public List<Product> searchProductsByNameOrCategory(String keyword) {
        return productInfoDAL.searchProduct(keyword);
    }

    @Override
    public Product getProductInfoById(String productId) {
        return productInfoDAL.getOneProductInfoById(productId, 1);
    }

    @Override
    public List<Product> getAllProducts() {
        return productInfoDAL.getAllProductsByState(-1, -1);
    }

    @Override
    public List<Product> getAvailableProductsByConsumer() {
        return productInfoDAL.getAllProductsByState(3, -1);
    }

    @Override
    public List<Product> getPurchasedProductByConsumer() {
        return Stream.concat(
                productInfoDAL.getAllProductsByState(4, 1).stream(),
                productInfoDAL.getAllProductsByState(5, 1).stream()
        ).collect(Collectors.toList());
    }

    @Override
    public List<Product> getPendingProductsByDealer() {
        return productInfoDAL.getAllProductsByState(1, -1);
    }

    @Override
    public List<Product> getPurchasedProductByDealer() {
        return Stream.concat(
                productInfoDAL.getAllProductsByState(2, 1).stream(),
                productInfoDAL.getAllProductsByState(3, 1).stream()
        ).collect(Collectors.toList());
    }

    @Override
    public Boolean importProductsFromOtherFiles(List<Product> newProducts) {
        return productInfoDAL.addMassiveProducts(newProducts) == newProducts.size();
    }

    @Override
    public Boolean purchaseByConsumer(String productId) {
        return productInfoDAL.updateOneProductState(productId, 4) > 0;
    }

    @Override
    public Boolean purchaseByDealer(String productId) {
        return productInfoDAL.updateOneProductState(productId, 2) > 0;
    }

    @Override
    public Boolean purchaseByDealerInBulk(String[] productIds) {
        return productInfoDAL.updateMassiveProductState(productIds, 2) > 0;
    }

    @Override
    public Boolean addTraceabilityPicture(Trace newTrace, Integer role) {
        switch (role) {
            case 0: return traceInfoDAL.addNewTrace(newTrace) > 0 &&
                    productInfoDAL.updateOneProductState(newTrace.getProductId(), 1) > 0;
            case 1: return traceInfoDAL.updateTraceByDealer(newTrace) > 0 &&
                    productInfoDAL.updateOneProductState(newTrace.getProductId(), 3) > 0;
            case 2: return traceInfoDAL.updateTraceByConsumer(newTrace) > 0 &&
                    productInfoDAL.updateOneProductState(newTrace.getProductId(), 5) > 0;
            default: return false;
        }
    }

    @Override
    public Boolean requestTraceability(Integer userId, String phoneNumber) {
        Integer verificationCode = new Random().nextInt(999999);

        String message = "您的防伪溯源查询验证码是：" + verificationCode + "，请在5分钟内使用。";

        Intent broadcastIntent = new Intent("SEND_SMS_ACTION");
        broadcastIntent.setPackage("iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem");
        broadcastIntent.putExtra("phoneNumber", phoneNumber);
        broadcastIntent.putExtra("message", message);

        sendBroadcast(broadcastIntent);

        SharedPreferences sharedPreferences = getSharedPreferences("vrCode", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        editor.putString("verificationCode", verificationCode.toString());
        editor.putLong("timestamp", System.currentTimeMillis());
        editor.apply();

        return true;
    }

    @Override
    public JSONObject verifyTraceability(Integer userId, String productId, String verifyCode) {
        JSONObject result = new JSONObject();

        sharedPreferences = getSharedPreferences("vrCode", MODE_PRIVATE);

        try {
            if (sharedPreferences == null) {
                return buildErrorResponse(result, "BAD REQUEST");
            }


            String code = sharedPreferences.getString("verificationCode", "");
            long timestamp = sharedPreferences.getLong("timestamp", 0);

            if (!code.equals(verifyCode)) {
                return buildErrorResponse(result, "验证码错误");
            }

            long currentTime = System.currentTimeMillis();
            long validityPeriod = 5 * 60 * 1000; // 5分钟
            if ((currentTime - timestamp) > validityPeriod) {
                return buildErrorResponse(result, "验证码已过期");
            }

            Trace resultTrace = traceInfoDAL.getTraceability(productId);
            if (resultTrace == null) {
                return buildErrorResponse(result, "BAD RESULT");
            }

            result.put("success", true);
            result.put("message", "查询到结果");
            result.put("resultTrace", resultTrace);
            result.put("resultProduct", productInfoDAL.getOneProductInfoById(productId, -1));

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return result;
    }

    private JSONObject buildErrorResponse(JSONObject result, String message) throws JSONException {
        result.put("success", false);
        result.put("message", message);
        return result;
    }
}
